#include <iostream>

using namespace std;

class Data
{
public:
    Data(int n = 0) : _n(n){cout << "Date(int n)" << endl;}
    ~Data(){cout << "~Data()" << endl;};
    void print() const{cout << "n = " << _n << endl;}
private:
    int _n;
};

class MiddleLayer
{
public:
    MiddleLayer(Data* pd = nullptr) : _pd(pd){cout << "MiddleLayer(Data* pd = nullptr)" << endl;}
    ~MiddleLayer(){cout << "~MiddleLayer()" << endl;if(_pd){delete _pd; _pd = nullptr;}}
    Data* operator->(){return _pd;}
    Data& operator*(){return *_pd;}
private:
    Data* _pd;
};

class ThirdLayer
{
public:
    ThirdLayer(MiddleLayer* pm = nullptr) : _pm(pm){cout << "ThirdLayer(MiddleLayer* _pm = nullptr)" << endl;}
    ~ThirdLayer(){cout << "~ThirdLayer()" << endl;if(_pm){delete _pm; _pm = nullptr;}}
    MiddleLayer& operator->(){return *_pm;};
    MiddleLayer& operator*(){return *_pm;};
private:
    MiddleLayer* _pm;
};

int main(void)
{
    MiddleLayer M(new Data (10));

    M.operator->()->print();
    M->print();
    (*M).print();

    cout << "______________________" << endl;

    ThirdLayer T(new MiddleLayer (new Data ()));

    T->print();
    T.operator->().operator->()->print();
    T.operator*().operator*().print();
    (*(*T)).print();

}